package com.firegod.course.controller;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.vod.model.v20170321.DeleteVideoRequest;
import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthRequest;
import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthResponse;
import com.firegod.commonutils.result.ResultCode;
import com.firegod.commonutils.vo.ResultVo;
import com.firegod.course.service.ChapterService;
import com.firegod.course.service.CourseService;
import com.firegod.course.service.ExcelService;
import com.firegod.course.service.VodService;
import com.firegod.servicebase.exceptionhandler.exception.GuliException;
import com.firegod.vod.constants.InitAliyunClient;
import com.firegod.vod.constants.VodConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/course")
@CrossOrigin
@Api(tags = "课程信息管理")
public class CourseController {

    @Autowired
    private CourseService courseService;

    @Autowired
    private ChapterService chapterService;

    @Autowired
    private VodService vodService;

    @Autowired
    private ExcelService excelService;

    @ApiOperation("创建课程")
    @PostMapping("/createCourse")
    public ResultVo createCourse(@RequestBody JSONObject jsonObject) {
        String cover = jsonObject.getString("cover");
        String description = jsonObject.getString("description");
        String title = jsonObject.getString("title");
        String semester = jsonObject.getString("semester");
        String tag = jsonObject.getString("tag");
        if (semester == null || tag == null || title == null ||
                semester.length() == 0 || tag.length() == 0 || title.length() == 0) {
            throw GuliException.from(ResultCode.NO_TITLE);
        }
        return ResultVo.ok().data("courseId", courseService.createCourse(title, semester, cover, description, tag));
    }

    @ApiOperation("学生加入课程")
    @PostMapping("/joinCourse")
    public ResultVo joinCourse(@RequestBody JSONObject jsonObject) {
        String courseId = jsonObject.getString("courseId");
        if (courseId == null || courseId.length() == 0) {
            throw GuliException.from(ResultCode.COURSE_NOT_EXIST);
        }
        courseService.joinCourse(courseId);
        return ResultVo.ok();
    }

    @ApiOperation("编辑课程")
    @PostMapping("/editCourse")
    public ResultVo editCourse(@RequestBody JSONObject jsonObject) {
        String courseId = jsonObject.getString("courseId");
        String cover = jsonObject.getString("cover");
        String description = jsonObject.getString("description");
        String title = jsonObject.getString("title");
        String semester = jsonObject.getString("semester");
        String tag = jsonObject.getString("tag");
        if (description == null || semester == null || tag == null || title == null ||
                description.length() == 0 || semester.length() == 0 || tag.length() == 0 || title.length() == 0) {
            throw GuliException.from(ResultCode.NO_TITLE);
        }
        courseService.editCourse(courseId, title, semester, cover, description, tag);
        return ResultVo.ok();
    }

    @ApiOperation("手动加入学生")
    @PostMapping("/addStudent")
    public ResultVo addStudent(@RequestBody JSONObject jsonObject) {
        String courseId = jsonObject.getString("courseId");
        String userId = jsonObject.getString("userId");
        String name = jsonObject.getString("name");
        if (courseId == null) {
            throw GuliException.from(ResultCode.COURSE_NOT_EXIST);
        }
        if (userId == null) {
            throw GuliException.from("请填写学号！");
        }
        return ResultVo.ok().data("studentList", courseService.addStudent(courseId, userId, name));
    }

    @ApiOperation("获取学生列表")
    @GetMapping("/studentList/{courseId}")
    public ResultVo getStudentList(@NotNull @PathVariable String courseId) {
        return ResultVo.ok().data("studentList", courseService.getStudentList(courseId));
    }

    @ApiOperation("获取课程列表")
    @PostMapping("/courseList")
    public ResultVo getCourseList(@RequestBody JSONObject jsonObject) {
        Integer limit = jsonObject.getInteger("limit");
        Integer offset = jsonObject.getInteger("offset");
        if (limit == null || offset == null) {
            throw GuliException.from("请输入页码和每页数量！");
        }
        return ResultVo.ok().data(courseService.getCourseList(limit, offset - 1));
    }

    @ApiOperation("删除视频")
    @PostMapping("/deleteVideo")
    public ResultVo deleteVideo(@RequestBody JSONObject jsonObject) {
        String videoId = jsonObject.getString("videoId");
        Long chapterId = jsonObject.getLong("chapterId");
        String courseId = jsonObject.getString("courseId");
        courseService.deleteVideo(courseId, chapterId, videoId);
        return ResultVo.ok();
    }

    @ApiOperation("获取推荐课程列表")
    @GetMapping("/recommendCourse/{limit}")
    public ResultVo recommendCourse(@PathVariable Integer limit) {
        if (limit == null) {
            throw GuliException.from("请输入要获取的推荐课程数量！");
        }
        return ResultVo.ok().data(courseService.getRecommendCourse(limit));
    }

    @ApiOperation("删除课程")
    @DeleteMapping("/deleteCourse/{courseId}")
    public ResultVo deleteCourse(@PathVariable String courseId) {
        courseService.deleteCourse(courseId);
        return ResultVo.ok();
    }

    @ApiOperation("添加章节")
    @PostMapping("/addChapter")
    public ResultVo addChapter(@RequestBody JSONObject jsonObject) {
        String courseId = jsonObject.getString("courseId");
        Integer sort = jsonObject.getInteger("sort");
        String title = jsonObject.getString("title");
        return ResultVo.ok().data(chapterService.addChapter(courseId, sort, title));
    }

    @ApiOperation("删除章节")
    @DeleteMapping("/deleteChapter/{chapterId}")
    public ResultVo deleteCourse(@PathVariable Long chapterId) {
        chapterService.deleteChapter(chapterId);
        return ResultVo.ok();
    }

    @ApiOperation("添加视频")
    @PostMapping("/addVideo")
    public ResultVo addVideo(@RequestBody JSONObject jsonObject) {
        String courseId = jsonObject.getString("courseId");
        String title = jsonObject.getString("title");
        String videoId = jsonObject.getString("videoId");
        Integer sort = jsonObject.getInteger("sort");
        Long chapterId = jsonObject.getLong("chapterId");
        if (videoId == null) {
            throw GuliException.from("添加失败，请检查上传是否成功！");
        }
        return ResultVo.ok().data(courseService.addVideo(courseId, chapterId, title, videoId));
    }

    @ApiOperation("上传视频到阿里云")
    @PostMapping(value = "/uploadAliyunVideo")
    public ResultVo uploadAliyunVideo(MultipartFile file) throws IOException {
        Optional.ofNullable(file).orElseThrow(() -> GuliException.from(ResultCode.FILE_EMPTY));
        String videoId = vodService.uploadVideoToAliyun(file);
        return ResultVo.ok().data("videoId", videoId);
    }

    @ApiOperation("根据视频id删除阿里云视频")
    @DeleteMapping("/removeAliyunVideo/{id}")
    public ResultVo removeAliyunVideo(@PathVariable String id) {
        //初始化阿里云客户端对象
        DefaultAcsClient client = InitAliyunClient.initVodClient(VodConstants.ACCESS_KEY_ID, VodConstants.ACCESS_KEY_SECRET);

        //创建删除视频的request对象
        DeleteVideoRequest deleteVideoRequest = new DeleteVideoRequest();
        deleteVideoRequest.setVideoIds(id);
        try {
            client.getAcsResponse(deleteVideoRequest);
        } catch (ClientException e) {
            e.printStackTrace();
            throw GuliException.from(ResultCode.DELETE_ERROR);
        }

        return ResultVo.ok();
    }

    @ApiOperation("删除多个阿里云视频")
    @DeleteMapping("/deleteBatch")
    public ResultVo deleteBatch(@RequestParam("videoIdList") List<String> videoIdList) {
        vodService.deleteBatch(videoIdList);
        return ResultVo.ok();
    }

    @ApiOperation("根据视频id获取视频凭证")
    @GetMapping("/getPlayAuth/{id}")
    public ResultVo getPlayAuth(@PathVariable String id) {

        //创建初始化对象
        DefaultAcsClient client = InitAliyunClient.initVodClient(VodConstants.ACCESS_KEY_ID, VodConstants.ACCESS_KEY_SECRET);

        //创建获取凭证的request和response对象
        GetVideoPlayAuthRequest authRequest = new GetVideoPlayAuthRequest();

        //向authRequest设置视频id
        authRequest.setVideoId(id);

        //调用方法得到凭证
        GetVideoPlayAuthResponse acsResponse;
        try {
            acsResponse = client.getAcsResponse(authRequest);
        } catch (ClientException e) {
            e.printStackTrace();
            throw GuliException.from(ResultCode.GET_PLAYAUTH_FAIL);
        }
        String playAuth = acsResponse.getPlayAuth();

        return ResultVo.ok().data("playAuth", playAuth);
    }

    @ApiOperation("根据课程id获取课程详情")
    @GetMapping("/findCourse/{courseId}")
    public ResultVo getCourse(@PathVariable @NotNull String courseId, String userId) {
        return ResultVo.ok().data("course", courseService.getCourseById(courseId, userId));
    }

    @ApiOperation("移除学生")
    @PostMapping("/deleteStudent")
    public ResultVo getCourse(@RequestBody JSONObject jsonObject) {
        String courseId = jsonObject.getString("courseId");
        String userId = jsonObject.getString("userId");
        courseService.deleteStudent(courseId, userId);
        return ResultVo.ok();
    }

    @PostMapping("/upload/{courseId}")
    @ApiOperation("上传excel")
    public ResultVo uploadExcel(@PathVariable String courseId, MultipartFile file) {
        try {
            //TODO 尚不清楚需求
            return ResultVo.ok().data("studentList", courseService.importStudent(courseId, excelService.registerStudentFromExcel(file)));
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVo.error().message(e.getMessage());
        }
    }
}
